module sim_cache(
  input clk,
  input rst,

  input direct,
  input invalid,
  input ren,
  input [63:0] raddr,
  input [3:0] rsize,
  output rbusy,
  output [63:0] rdata, 
  output rdata_valid,

  output wbusy,
  input wen,
  input [63:0] waddr,
  input [63:0] wdata, 
  input [3:0] wsize
);
  wire [5:0] io_sram0_addr;
  wire io_sram0_cen;
  wire io_sram0_wen;
  wire [127:0] io_sram0_wmask;
  wire [127:0] io_sram0_wdata;
  wire [127:0] io_sram0_rdata;

  wire [5:0] io_sram1_addr;
  wire io_sram1_cen;
  wire io_sram1_wen;
  wire [127:0] io_sram1_wmask;
  wire [127:0] io_sram1_wdata;
  wire [127:0] io_sram1_rdata;

  wire [5:0] io_sram2_addr;
  wire io_sram2_cen;
  wire io_sram2_wen;
  wire [127:0] io_sram2_wmask;
  wire [127:0] io_sram2_wdata;
  wire [127:0] io_sram2_rdata;

  wire [5:0] io_sram3_addr;
  wire io_sram3_cen;
  wire io_sram3_wen;
  wire [127:0] io_sram3_wmask;
  wire [127:0] io_sram3_wdata;
  wire [127:0] io_sram3_rdata;
  
S011HD1P_X32Y2D128_BW isnt_sram0(
  .Q(io_sram0_rdata),
  .CLK(clk),
  .CEN(io_sram0_cen),
  .WEN(io_sram0_wen),
  .BWEN(io_sram0_wmask),
  .A(io_sram0_addr),
  .D(io_sram0_wdata)
);
S011HD1P_X32Y2D128_BW isnt_sram1(
  .Q(io_sram1_rdata),
  .CLK(clk),
  .CEN(io_sram1_cen),
  .WEN(io_sram1_wen),
  .BWEN(io_sram1_wmask),
  .A(io_sram1_addr),
  .D(io_sram1_wdata)
);
S011HD1P_X32Y2D128_BW isnt_sram2(
  .Q(io_sram2_rdata),
  .CLK(clk),
  .CEN(io_sram2_cen),
  .WEN(io_sram2_wen),
  .BWEN(io_sram2_wmask),
  .A(io_sram2_addr),
  .D(io_sram2_wdata)
);
S011HD1P_X32Y2D128_BW isnt_sram3(
  .Q(io_sram3_rdata),
  .CLK(clk),
  .CEN(io_sram3_cen),
  .WEN(io_sram3_wen),
  .BWEN(io_sram3_wmask),
  .A(io_sram3_addr),
  .D(io_sram3_wdata)
);
  

  wire dcache_mem_rbusy;
  wire dcache_mem_ren;
  wire [3:0] dcache_mem_rsize;
  wire [31:0] dcache_mem_raddr;
  wire reg [63:0] dcache_mem_rdata;
  wire reg dcache_mem_rdata_valid;

  wire dcache_mem_wbusy;
  wire dcache_mem_wen;
  wire [3:0] dcache_mem_wsize;
  wire [31:0] dcache_mem_waddr;
  wire [63:0] dcache_mem_wdata;

  cache inst_cache
  (
    .clk         (clk),
    .rst         (rst),
    .direct      (direct),
    .invalid     (invalid),
    .ren         (ren),
    .raddr       (raddr),
    .rsize       (rsize),
    .rbusy       (rbusy),
    .rdata       (rdata),
    .rdata_valid (rdata_valid),
    .wbusy       (wbusy),
    .wen         (wen),
    .waddr       (waddr),
    .wdata       (wdata),
    .wsize       (wsize),
    .io_sram0_addr  (io_sram0_addr),
    .io_sram0_cen   (io_sram0_cen),
    .io_sram0_wen   (io_sram0_wen),
    .io_sram0_wmask (io_sram0_wmask),
    .io_sram0_wdata (io_sram0_wdata),
    .io_sram0_rdata (io_sram0_rdata),
    .io_sram1_addr  (io_sram1_addr),
    .io_sram1_cen   (io_sram1_cen),
    .io_sram1_wen   (io_sram1_wen),
    .io_sram1_wmask (io_sram1_wmask),
    .io_sram1_wdata (io_sram1_wdata),
    .io_sram1_rdata (io_sram1_rdata),
    .io_sram2_addr  (io_sram2_addr),
    .io_sram2_cen   (io_sram2_cen),
    .io_sram2_wen   (io_sram2_wen),
    .io_sram2_wmask (io_sram2_wmask),
    .io_sram2_wdata (io_sram2_wdata),
    .io_sram2_rdata (io_sram2_rdata),
    .io_sram3_addr  (io_sram3_addr),
    .io_sram3_cen   (io_sram3_cen),
    .io_sram3_wen   (io_sram3_wen),
    .io_sram3_wmask (io_sram3_wmask),
    .io_sram3_wdata (io_sram3_wdata),
    .io_sram3_rdata (io_sram3_rdata),
    .mem_rbusy       (dcache_mem_rbusy),
    .mem_ren         (dcache_mem_ren),
    .mem_rsize       (dcache_mem_rsize),
    .mem_raddr       (dcache_mem_raddr),
    .mem_rdata       (dcache_mem_rdata),
    .mem_rdata_valid (dcache_mem_rdata_valid),
    .mem_wbusy       (dcache_mem_wbusy),
    .mem_wen         (dcache_mem_wen),
    .mem_wsize       (dcache_mem_wsize),
    .mem_waddr       (dcache_mem_waddr),
    .mem_wdata       (dcache_mem_wdata)
    
  );
  wire io_master_awready;
  wire io_master_awvalid;
  wire [31:0] io_master_awaddr;
  wire [3:0] io_master_awid;
  wire [7:0] io_master_awlen;
  wire [2:0] io_master_awsize;
  wire [1:0] io_master_awburst;

  wire io_master_wready;
  wire io_master_wvalid;
  wire [63:0] io_master_wdata;
  wire [7:0] io_master_wstrb;
  wire io_master_wlast;

  wire io_master_bready;
  wire io_master_bvalid;
  wire [1:0] io_master_bresp;
  wire [3:0] io_master_bid;

  wire io_master_arready;
  wire io_master_arvalid;
  wire [31:0] io_master_araddr;
  wire [3:0] io_master_arid;
  wire [7:0] io_master_arlen;
  wire [2:0] io_master_arsize;
  wire [1:0] io_master_arburst;

  wire io_master_rready;
  wire io_master_rvalid;
  wire [1:0] io_master_rresp;
  wire [63:0] io_master_rdata;
  wire io_master_rlast;
  wire [3:0] io_master_rid;

  wire clint_wen;
  wire clint_ren;
  wire [31:0] clint_raddr;
  wire [31:0] clint_waddr;
  wire [63:0] clint_wdata;
  wire [3:0] clint_wsize;
  wire [63:0] clint_rdata;
  wire [3:0] clint_rsize;
  wire clint_rdata_valid;

  wire icache_mem_rbusy,icache_mem_rdata_valid;
  wire [63:0] icache_mem_rdata;

  MemBus inst_MemBus
    (
      .clk                    (clk),
      .rst                    (rst),
      .dcache_mem_rbusy       (dcache_mem_rbusy),
      .dcache_mem_ren         (dcache_mem_ren),
      .dcache_mem_rsize       (dcache_mem_rsize),
      .dcache_mem_raddr       (dcache_mem_raddr),
      .dcache_mem_rdata       (dcache_mem_rdata),
      .dcache_mem_rdata_valid (dcache_mem_rdata_valid),
      .dcache_mem_wbusy       (dcache_mem_wbusy),
      .dcache_mem_wen         (dcache_mem_wen),
      .dcache_mem_wsize       (dcache_mem_wsize),
      .dcache_mem_waddr       (dcache_mem_waddr),
      .dcache_mem_wdata       (dcache_mem_wdata),
      .icache_mem_rbusy       (icache_mem_rbusy),
      .icache_mem_ren         (1'b0),
      .icache_mem_rsize       (4'b0),
      .icache_mem_raddr       (32'b0),
      .icache_mem_rdata       (icache_mem_rdata),
      .icache_mem_rdata_valid (icache_mem_rdata_valid),
      .clint_wen              (clint_wen),
      .clint_ren              (clint_ren),
      .clint_raddr            (clint_raddr),
      .clint_waddr            (clint_waddr),
      .clint_wdata            (clint_wdata),
      .clint_wsize            (clint_wsize),
      .clint_rdata            (clint_rdata),
      .clint_rsize            (clint_rsize),
      .clint_rdata_valid      (clint_rdata_valid),
      .io_master_awready      (io_master_awready),
      .io_master_awvalid      (io_master_awvalid),
      .io_master_awaddr       (io_master_awaddr),
      .io_master_awid         (io_master_awid),
      .io_master_awlen        (io_master_awlen),
      .io_master_awsize       (io_master_awsize),
      .io_master_awburst      (io_master_awburst),
      .io_master_wready       (io_master_wready),
      .io_master_wvalid       (io_master_wvalid),
      .io_master_wdata        (io_master_wdata),
      .io_master_wstrb        (io_master_wstrb),
      .io_master_wlast        (io_master_wlast),
      .io_master_bready       (io_master_bready),
      .io_master_bvalid       (io_master_bvalid),
      .io_master_bresp        (io_master_bresp),
      .io_master_bid          (io_master_bid),
      .io_master_arready      (io_master_arready),
      .io_master_arvalid      (io_master_arvalid),
      .io_master_araddr       (io_master_araddr),
      .io_master_arid         (io_master_arid),
      .io_master_arlen        (io_master_arlen),
      .io_master_arsize       (io_master_arsize),
      .io_master_arburst      (io_master_arburst),
      .io_master_rready       (io_master_rready),
      .io_master_rvalid       (io_master_rvalid),
      .io_master_rresp        (io_master_rresp),
      .io_master_rdata        (io_master_rdata),
      .io_master_rlast        (io_master_rlast),
      .io_master_rid          (io_master_rid)
    );
    AXI4_memory inst_AXI4_memory
    (
      .clk              (clk),
      .rst              (rst),
      .io_slave_awready (io_master_awready),
      .io_slave_awvalid (io_master_awvalid),
      .io_slave_awaddr  (io_master_awaddr),
      .io_slave_awid    (io_master_awid),
      .io_slave_awlen   (io_master_awlen),
      .io_slave_awsize  (io_master_awsize),
      .io_slave_awburst (io_master_awburst),
      .io_slave_wready  (io_master_wready),
      .io_slave_wvalid  (io_master_wvalid),
      .io_slave_wdata   (io_master_wdata),
      .io_slave_wstrb   (io_master_wstrb),
      .io_slave_wlast   (io_master_wlast),
      .io_slave_bready  (io_master_bready),
      .io_slave_bvalid  (io_master_bvalid),
      .io_slave_bresp   (io_master_bresp),
      .io_slave_bid     (io_master_bid),
      .io_slave_arready (io_master_arready),
      .io_slave_arvalid (io_master_arvalid),
      .io_slave_araddr  (io_master_araddr),
      .io_slave_arid    (io_master_arid),
      .io_slave_arlen   (io_master_arlen),
      .io_slave_arsize  (io_master_arsize),
      .io_slave_arburst (io_master_arburst),
      .io_slave_rready  (io_master_rready),
      .io_slave_rvalid  (io_master_rvalid),
      .io_slave_rresp   (io_master_rresp),
      .io_slave_rdata   (io_master_rdata),
      .io_slave_rlast   (io_master_rlast),
      .io_slave_rid     (io_master_rid)
    );
    wire tim_int_req,msip_o,msip_valid_o;
    reg msip;
    always @(posedge clk) begin
      if(rst) msip <= 1'b0;
      else if(msip_valid_o) msip <= msip_o;
    end
    CoreLocalInterrupt inst_CoreLocalInterrupt
    (
      .clk          (clk),
      .rst          (rst),
      .wen          (clint_wen),
      .ren          (clint_ren),
      .raddr        (clint_raddr),
      .waddr        (clint_waddr),
      .wdata        (clint_wdata),
      .wsize        (clint_wsize),
      .rsize        (clint_rsize),
      .rdata        (clint_rdata),
      .rdata_valid  (clint_rdata_valid),
      .tim_int_req  (tim_int_req),
      .msip_i       (msip),
      .msip_o       (msip_o),
      .msip_valid_o (msip_valid_o)
    );

endmodule
